package cn.highedu.spring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 定义一个切面类 为所有的Dao类中的方法加入日志
 */
@Component // 交给Spring容器管理
@Aspect // 声明这是一个切面类
public class LoggerAspect {
    // 在执行目标方法之前执行当前方法(切入点表达式)
    /**
     * 切入点表达式()
     * execution 切入点表达式的开始
     * 第一个星号表示执行的目标方法可以是任意返回值类型
     * 第二个星号表示某一个包下的任意类
     * 第三个星号表示任意方法
     * 括号里的两个点表示方法可以有任意参数
     */
    @Before("execution(* cn.highedu.spring.aop.*.*(..))")
    public void beforeLogger() {
        System.out.println(new Date() + "--> 开始执行");
    }

    /**
     * 统一管理切入点
     */
    @Pointcut("execution(* cn.highedu.spring.aop.*.save*(..)) || " +
            "execution(* cn.highedu.spring.aop.*.delete*(..)) || " +
            "execution(* cn.highedu.spring.aop.*.update*(..))")
    public void pointCut() {}
    /**
     * 以save、delete、update开头的方法加入日志信息
     */
    @After("pointCut()")
    public void afterLogger() {
        System.out.println(new Date() + "--> 结束执行 后置通知");
    }
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println(new Date() + "--> 开始环绕通知");
        try {
            return point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw throwable;
        }finally {
            System.out.println(new Date() + "--> 结束环绕通知");
        }
    }
}
